<!-- 消费定额 -->
<template>
  <view class="relative order-details page-root">
    <nav-bar color="white" bg-color="black" title="收银台" show-back></nav-bar>

    <view class="flex p-10rpx flex-auto h-full">
      <view class="flex-1 mx-5rpx bg-white p-20rpx rounded-md flex-col">
        <view class="h-full flex-auto flex flex-col justify-center items-center">
          <view class="text-base flex-col p-10rpx justify-center items-center text-center">
            <text class="block text-gray-400 text-base">固定收款金额</text>
            <view class="font-bold my-10rpx flex items-end justify-center">
              <text class="text-sm">￥</text>
              <text class="block text-xxl"> {{ formatMoney(formData.chargeMoney) || "0.00" }}</text>
            </view>
            <u-button
              v-if="isOpenQuotaPay"
              type="error"
              size="large"
              custom-style="padding:10rpx 20rpx;"
              @click="isOpenQuotaPay = false"
              icon="lock"
              >解锁</u-button
            >
          </view>

          <view class="text-base flex items-end mb-10rpx flex-auto">
            <u-button
              v-if="isOpenQuotaPay"
              type="warning"
              size="large"
              custom-style="padding:10rpx 20rpx;margin-right:10rpx"
              @click="onClickMemberLogin"
              icon="level"
              >会员卡查询</u-button
            >

            <u-button
              v-else
              :disabled="!formData.chargeMoney"
              color="#1684fc"
              size="large"
              custom-style="padding:10rpx 20rpx;margin-right:10rpx"
              @click="isOpenQuotaPay = true"
              >开启定额收款</u-button
            >
          </view>
        </view>
      </view>

      <view v-if="!isOpenQuotaPay" class="flex flex-col flex-1 mx-5rpx p-10rpx rounded-md bg-white">
        <view class="absolute">
          <u-icon
            @click="() => refSettingPopup.open()"
            name="setting-fill"
            color="#1684fc"
            label-color="#1684fc"
            size="12rpx"
          ></u-icon>
        </view>
        <cash-pay
          ref="refCashPay"
          title="设置固定消费金额"
          subTitle="设定金额后客户可直接支付进行消费"
          confirmText="确认"
          @pay-finish="onCashPayFinish"
          @pay-clear="formData.chargeMoney = 0"
          :skipPayment="true"
        >
          设定金额后客户可直接支付进行消费
        </cash-pay>
      </view>
      <view v-else class="flex flex-col flex-1 mx-5rpx p-20rpx rounded-md bg-white">
        <text class="block text-base text-center p-20rpx text-gray-500"> 选择支付方式手动收银 </text>
        <view class="text-base flex items-start mb-10rpx flex-auto flex-wrap">
          <u-button
            type="warning"
            size="normal"
            custom-style="padding:20rpx 20rpx;margin-right:10rpx"
            @click="openMerberPay"
            icon="level"
            >会员卡支付</u-button
          >

          <u-button
            :disabled="!formData.chargeMoney"
            color="#1684fc"
            size="normal "
            icon="scan"
            icon-color="white"
            custom-style="padding:20rpx 20rpx;margin-right:10rpx"
            @click="openScanBoxPay"
            >扫码支付</u-button
          >

          <u-button
            type="error"
            size="normal"
            custom-style="padding:20rpx 20rpx;margin-right:10rpx"
            @click="openCashPayPopup"
            icon="coupon"
            >现金收款</u-button
          >

          <u-button
            type="success"
            size="normal"
            custom-style="padding:20rpx 20rpx;margin-right:10rpx"
            @click="openFacePayPopup"
            icon="coupon"
            >会员人脸支付</u-button
          >
        </view>
      </view>
    </view>

    <!-- 备注设置弹窗 -->
    <common-popup ref="refRemarkPopup" @confirm="popupRemarkConfirm" />

    <!-- 支付弹窗 -->
    <resultPopup ref="refCommonPopup" :show-icon="false">
      <template #default="{ result }">
        <view
          v-if="result.dataType == 'cash' && result.state === 'paying'"
          class="mt-20rpx flex-col items-center justify-center text-center"
        >
          <text class="block text-base py-10rpx text-gray-400"> 找零 </text>
          <text class="block font-bold"> {{ result.giveChange || "0.00" }} 元 </text>
        </view>
        <view class="flex-col" v-else-if="result.dataType == 'scan' && result.state === 'paying'">
          <!-- 扫码支付 -->
          <scanPay :skipPayment="true" :show-paytype="true" :qrSize="200" @pay-finish="onPayFinish">
            <template #title>
              <view class="flex-col items-center justify-center text-center">
                <text class="block text-base text-gray-500"> 待收款金额: </text>
                <view class="mt-5rpx flex items-end">
                  <text class="block text-sm"> ￥ </text>
                  <text class="block text-xl font-bold"> {{ formatMoney(formData.chargeMoney) }} </text>
                </view>
              </view>
            </template>
          </scanPay>
        </view>
        <!-- 会员刷卡支付 -->
        <view class="flex-col" v-else-if="result.dataType == 'card' && result.state === 'paying'">
          <merberPay @pay-finish="onPayFinish" :hookPlaceAnOrder="hookPlaceAnOrder">
            <template #title>
              <view class="flex-col items-center justify-center text-center">
                <text class="block text-base text-gray-500"> 待收款金额: </text>
                <view class="mt-5rpx flex items-end">
                  <text class="block text-sm"> ￥ </text>
                  <text class="block text-xl font-bold"> {{ formatMoney(formData.chargeMoney) }} </text>
                </view>
              </view>
            </template>
          </merberPay>
        </view>
        <!-- 会员人脸支付 -->
        <view class="flex-col" v-else-if="result.dataType == 'face' && result.state === 'paying'">
          <facePay @pay-finish="onPayFinish" :hookPlaceAnOrder="hookPlaceAnOrder">
            <template #title>
              <view class="flex-col items-center justify-center text-center">
                <text class="block text-base text-gray-500"> 待收款金额: </text>
                <view class="mt-5rpx flex items-end">
                  <text class="block text-sm"> ￥ </text>
                  <text class="block text-xl font-bold"> {{ formatMoney(formData.chargeMoney) }} </text>
                </view>
              </view>
            </template>
          </facePay>
        </view>

        <!-- 会员卡支付成功显示会员信息 -->
        <comMerberInfo v-else-if="result.dataType == 'card' && result.state === 'success'" :info="result.merberInfo" />
      </template>
      <template #confirm="{ config }">
        <view class="btns flex" v-if="config.state != 'success'">
          <view class="btns-item" @click="refCommonPopup.close()">
            <text class="btns-item-txt"> 取消支付 </text>
          </view>
        </view>
      </template>
    </resultPopup>

    <nfc-popup ref="refNfcPopup" />

    <!-- <merber-info-popup ref="refMerberLoginPopup" @confirm="onMerberLogin" /> -->

    <!-- 会员信息弹窗 -->
    <resultPopup ref="refMerberInfoPopup" :show-icon="false">
      <template #default>
        <comMerberInfo :info="merberInfo" />
      </template>
      <template #confirm="{ config }">
        <view class="btns flex">
          <view class="btns-item" @click="refMerberInfoPopup.close(), (merberInfo = {})">
            <text class="btns-item-txt"> 关闭 </text>
          </view>
        </view>
      </template>
    </resultPopup>
  </view>
</template>
<script lang="ts" setup>
import { onLoad } from "@dcloudio/uni-app";
import { reactive, ref, onMounted, onBeforeUnmount } from "vue";

import resultPopup from "@/components/common-popup/result-popup.vue";
import CashPay from "../place-order/components/com-pay-dialog/cash-pay.vue";
import scanPay from "../place-order/components/com-pay-dialog/scan-pay.vue";
import merberPay from "../place-order/components/com-pay-dialog/merber-pay.vue";
import facePay from "../place-order/components/com-pay-dialog/face-pay.vue";
import comMerberInfo from "../place-order/components/com-merber-info.vue";

import { fixedConsumption, getCustomerInfoByCard } from "@/api";
import { formatMoney } from "@/utils/util";
import { useStore } from "vuex";
import baseConfig from "@/common/config";
import dayjs from "dayjs";
import { openSubScreen } from "@/utils/sceeenUtils";
import { noOrderPrintTick } from "@/pages/subReportForm/print-config/print-utils";
import { loopCheckOrderStatus } from './cashierUtils'

const store = useStore();

// TODO 收款成功应立即弹窗，打印等逻辑不应该影响 收款结果（待）

// 是否已开启定额收款模式
const isOpenQuotaPay = ref(false);

const pageStatus = reactive({
  loading: false,
  // #ifdef H5
  showDebug: true,
  // #endif
});

// 页面传递的参数
const pagePam = {
  id: "",
};

const formData = reactive({
  remark: "",
  chargeMoney: 0,
  // 前端自建的流水号 （...）
  serialNumber: new Date().getTime() + Math.floor(Math.random() * 1000),
});

onLoad((e: any) => {
  console.log("onLoad:>", e);
  if (e.id) pagePam.id = e.id;
  // loadSysDict(["sys_payType"]);
});

const details = ref({
  payType: "",
});

onMounted(async () => {
  // await getPageData();
});

onBeforeUnmount(() => {
  // 恢复客户屏幕的显示为默认
  openSubScreen();
});

const onCashPayFinish = ({ type, money }) => {
  if (type === "success") {
    console.log("收款结束：", { type, money });
    formData.chargeMoney = money;
  }
};

// 备注

const refRemarkPopup = ref();

const popupConfig = {
  title: "备注",
  content: "",
  confirmText: "保存",
  cancelText: "取消",
};

// 添加备注
const addRemark = () => {
  popupConfig.content = formData.remark;
  refRemarkPopup.value.open(popupConfig);
};

const popupRemarkConfirm = (data) => {
  formData.remark = data;
};

/** -------  设置 ----------- */

// 支付弹窗
const refCommonPopup = ref();

const openScanBoxPay = async () => {
  const popupConfig = {
    title: "扫码盒子收款",
    content: "",
    cancelText: "取消支付",
    autoClose: false,
    //----- 自定义数据
    dataType: "scan",
    state: "paying",
  };

  refCommonPopup.value.open(popupConfig);
};

const refCashPay = ref();
const openCashPayPopup = async () => {
  try {
    uni.showLoading();
    const { businessId, abbreviation } = store.getters.businessInfo;
    // 调用收款接口(通知现金收款)
    console.log("merberInfo.value:", merberInfo.value);
    // 创建唯一的消费流水号 如1894270237119668226
    formData.serialNumber = new Date().getTime() + Math.floor(Math.random() * 1000);
    const pam = {
      customerId: /* merberInfo.value?.customerInformationId || */ "", //用户id
      cardCode: /* merberInfo.value?.logicalCardNumber || */ "", //卡号、支付授权码
      commandType: "20",
      balance: formData.chargeMoney * 100, //金额(分)
      deviceCode: store.getters.deviceId, //设备号
      payMethod: "5", // 支付方式 1- 刷卡支付 2- 刷脸支付 3- 二维码支付 4-身份证号 5 - 现金支付
      cstmId: businessId, //商户id
      tenantId: baseConfig.getTenantId(), //租户
      swipeTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), //刷卡时间
      serialNumber: formData.serialNumber,
    };
    const { data, success } = await fixedConsumption(pam);
    // const { data, success } = await xxxx(pam)
    if (!success) throw new Error("操作失败");
    uni.hideLoading();
    // 打印程序启动
    const price = formatMoney(formData.chargeMoney);
    noOrderPrintTick({
      merchname: abbreviation,
      orderNo: formData.serialNumber,
      // opuser: "收银员",
      time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
      goodslist: [
        {
          foodName: "",
          number: 1,
          price: price,
          totel: price,
        },
      ],
      remark: formData.remark,
      total: price,
      fee: price,
      foot: "欢迎下次光临",
    });
    const popupConfig = {
      title: "收款成功",
      closeInAfter: 5000,
      showIcon: true,
      autoClose: true,
      content: "",
      // 自定义信息
      state: "success",
      dataType: "none",
    };
    refCommonPopup.value.open(popupConfig);
    // 清除数据(固定消费不清除金额数据)
    // formData.chargeMoney = 0;
    // refCashPay.value.clear();

    formData.remark = "";
  } catch (error: any) {
    console.error("收款失败:", error, error.message);
    refCommonPopup.value.open({
      title: "收款失败",
      showIcon: true,
      autoClose: false,
      content: error.data?.msg || error.message || "",
      type: "fail",
      // 自定义信息
      state: "success",
      dataType: "none",
    });
    uni.hideLoading();
  }
};

const onPayFinish = ({ payBean, result, money }) => {
  const { orderId: parentId } = payBean;

  console.log("onPayFinish:", { payBean, result });
  // 更新客户屏
  openSubScreen();

  const popupConfig = {
    title: "收款成功",
    closeInAfter: 5000,
    showIcon: true,
    autoClose: true,
    content: "",
    // 自定义信息
    state: "success",
    dataType: payBean.payType || "none",
    merberInfo: {},
  };
  switch (payBean.status) {
    case "success":
      uni.hideLoading();
      if ((payBean.payType === "card" || payBean.payType === "face") && payBean.status === "success") {
        // 打印程序启动
        const price = formatMoney(formData.chargeMoney);
        const { businessId, abbreviation } = store.getters.businessInfo;
        noOrderPrintTick({
          merchname: abbreviation,
          orderNo: "",
          opuser: "收银员",
          time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
          goodslist: [
            {
              foodName: "",
              number: 1,
              price: price,
              totel: price,
            },
          ],
          remark: formData.remark,
          total: price,
          fee: price,
          foot: "欢迎下次光临",
        });
        // payMerber 只有会员支付时才有
        popupConfig.merberInfo = payBean.payMerber;

        refCommonPopup.value.open(popupConfig);
        // 清除数据 (固定消费不清除金额数据)
        // formData.chargeMoney = 0;
        // refCashPay.value.clear();
        formData.remark = "";
        console.log("支付成功");
      } else if (payBean.payType === "scan") {
        // 自行处理的支付下单逻辑
        return scanPlaceAnOrder(payBean.payCode, payBean.codeType);
      } else {
        console.warn("暂不支持处理的支付类型！");
      }
      break;
    case "fail":
      console.log("支付失败");
      break;
    case "cancel":
      console.log("取消支付");
      break;
    default:
  }
};

// 会员卡支付
const openMerberPay = async () => {
  const popupConfig = {
    title: "会员卡收款",
    content: "",
    cancelText: "取消支付",
    autoClose: false,
    //----- 自定义数据
    dataType: "card",
    state: "paying",
  };

  refCommonPopup.value.open(popupConfig);
};

const openFacePayPopup = async () => {
  const popupConfig = {
    title: "会员人脸收款",
    content: "",
    cancelText: "取消支付",
    autoClose: false,
    //----- 自定义数据
    dataType: "face",
    state: "paying",
  };

  refCommonPopup.value.open(popupConfig);
};

// 扫码支付 自定义下单方法
const scanPlaceAnOrder = async (payCode: string, codeType: string) => {
  console.log("scanPlaceAnOrder:", { payCode, codeType });
  try {
    uni.showLoading({mask: true});
    const { businessId, abbreviation } = store.getters.businessInfo;
    // 创建唯一的消费流水号 如1894270237119668226
    const serialNumber = new Date().getTime() + Math.floor(Math.random() * 1000);

    // 调用收款接口
    const pam = {
      // 会员已登录的情况下传会员信息，没登陆不传（游客下单）
      customerId: /* merberInfo.value.customerInformationId ||  */ "", //用户id
      cardCode: payCode || "", //卡号、支付授权码 （！！！！）
      commandType: "20",
      balance: formData.chargeMoney * 100, //金额(分)
      deviceCode: store.getters.deviceId, //设备号
      payMethod: "3", // 支付方式 1- 刷卡支付 2- 刷脸支付 3- 二维码支付 4-身份证号 5 - 现金支付
      cstmId: businessId, //商户id
      tenantId: baseConfig.getTenantId(), //租户
      swipeTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), //刷卡时间
      serialNumber,
    };
    const { data, success } = await fixedConsumption(pam);
    if (!success) throw new Error("操作失败");
    fixedConsumptionCheck({ data, success });

    // （第三方支付逻辑补充）下单没有错误后轮询查询订单状态看是否支付成功
    uni.hideLoading();
    uni.showLoading({mask: true, title: "订单查询中..."});
    await loopCheckOrderStatus(data.buffetOrderId);

    uni.hideLoading();
    refCommonPopup.value.open({
      title: "收款成功",
      closeInAfter: 5000,
      showIcon: true,
      autoClose: true,
      content: "",
      // 自定义信息
      state: "success",
      dataType: "scan",
    });
    const price = formatMoney(formData.chargeMoney);
    // 打印程序启动
    noOrderPrintTick({
      merchname: abbreviation,
      orderNo: serialNumber,
      // opuser: "收银员",
      time: dayjs().format("YYYY-MM-DD HH:mm:ss"),
      goodslist: [
        {
          foodName: "",
          number: 1,
          price: price,
          totel: price,
        },
      ],
      remark: formData.remark,
      total: price,
      fee: price,
      foot: "欢迎下次光临",
    });
  } catch (error) {
    console.error("收款失败:", error);
    uni.hideLoading();
    refCommonPopup.value.open({
      title: "收款失败",
      showIcon: true,
      autoClose: false,
      content: error.data?.msg || error.message || "",
      type: "fail",
      // 自定义信息
      state: "fail",
      dataType: "scan",
    });
  }
};

// 会员卡 自定义下单方法（hook 支付组件）
const hookPlaceAnOrder = async (cardInfo: any) => {
  console.log("hookPlaceAnOrder:", cardInfo);
  // 支付使用的会员（已经登陆的情况下返回登录的会员，未登录直接刷卡的情况返回刷卡识别的会员）
  const payMember = cardInfo.member;
  try {
    uni.showLoading();
    const { businessId } = store.getters.businessInfo;

    // 创建唯一的消费流水号 如1894270237119668226
    const serialNumber = new Date().getTime() + Math.floor(Math.random() * 1000);

    // 调用收款接口
    const pam = {
      customerId: payMember.customerInformationId || "", //用户id
      cardCode: payMember.logicalCardNumber || "", //卡号、支付授权码
      commandType: "20",
      balance: formData.chargeMoney * 100, //金额(分)
      deviceCode: store.getters.deviceId, //设备号
      payMethod: "1", // 支付方式 1- 刷卡支付 2- 刷脸支付 3- 二维码支付 4-身份证号 5 - 现金支付
      cstmId: businessId, //商户id
      tenantId: baseConfig.getTenantId(), //租户
      swipeTime: dayjs().format("YYYY-MM-DD HH:mm:ss"), //刷卡时间
      serialNumber, // 消费流水号，同一笔收费重发时流水号不改变
    };
    const { data, success } = await fixedConsumption(pam);
    if (!success) throw new Error("操作失败");
    fixedConsumptionCheck({ data, success });
    uni.hideLoading();
    return {
      data: "",
      success: true,
      msg: "ok",
      skipPay: true,
    };
  } catch (error) {
    console.error("收款失败:", error);
    uni.hideLoading();
    return {
      data: "",
      success: false,
      msg: error.data?.msg || error.message || "收款失败",
      skipPay: true,
    };
  }
};

/** 会员登录 (读卡 && 刷脸) */
const merberInfo = ref({});

const refMerberInfoPopup = ref();
const onClickMemberLogin = () => {
  // 判断是否已经登录
  if (merberInfo.value && merberInfo.value.customerInformationId) {
    // 已登录打开信息弹窗
    refMerberInfoPopup.value.open({ title: "会员信息" });
  } else {
    // 未登录 打开读卡器读取进行登录
    startReadCard();
  }
};

// fixedConsumption 支付返回检查（只检查错误）
const fixedConsumptionCheck = (res: any) => {
  if (!res.success) throw new Error("支付处理失败");
  if (res.data) {
    /**
     * resultCode："0 成功 1 无此卡 2挂失 3注销 4支付未完成 10 余额不足 11 停用时段（卡片停用） 12 非本系统卡片 13 处理失败 14 停用时段（不在刷卡时间段内） 15 本餐消费超次数"
     */
    const resultCode = res.data.resultCode;
    const errorMessages = {
      1: "无此卡",
      2: "卡片已挂失",
      3: "卡片已注销",
      4: "支付未完成",
      10: "余额不足",
      11: "卡片已停用",
      12: "非本系统卡片",
      13: "处理失败",
      14: "不在刷卡时间段内",
      15: "本餐消费超次数",
    };
    if (resultCode != "0") {
      throw new Error(errorMessages[resultCode] || res.data.errorText);
    }
  } else {
    throw new Error("支付处理失败 #4");
  }
};

// 退出登录
const onClickMemberLogout = () => {
  refMerberInfoPopup.value.close();
  merberInfo.value = {};
  // 清除会员登录信息，防止支付组件错误读取会员信息）
  store.commit("shoppingCard/setCurrShoppingCard", {
    useMember: false, // 是否登录会员
    member: {}, // 会员信息 useMember = true 时使用,
  });
  uni.showToast({ title: "已退出登录", icon: "none" });
};

// 读卡
const refNfcPopup = ref();

const startReadCard = async () => {
  console.log("开始读卡");
  try {
    const card = await refNfcPopup.value.reading();
    console.log("读卡结束", card);
    if (card) {
      // 查询会员信息
      const { data } = await getCustomerInfoByCard({ physicalCardNumber: card });
      if (!data) throw new Error("会员信息不存在");
      merberInfo.value = data;
      // uni.showToast({ title: "登录成功", icon: "success" });
      // 结束后直接弹出会员信息弹窗
      refMerberInfoPopup.value.open({ title: "会员信息" });
    }
  } catch (error) {
    console.error("读卡失败", error);
  }
};
</script>
<style lang="scss" scoped>
.page-root {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.order-details {
  // height: 90vh;
  box-sizing: border-box;

  .food-list {
    width: 100%;
    min-width: none !important;
  }

  ::v-deep .uni-table {
    min-width: auto !important;
  }

  .details-text {
    font-size: 10rpx;
    white-space: nowrap;
    overflow: scroll;

    &.d-name {
      color: rgb(179, 179, 179);
    }

    &.d-price {
      color: red;
      font-weight: bold;
    }

    &.d-price-back {
      color: rgb(14, 187, 52);
      font-weight: bold;
    }
    &.d-price-discount {
      color: orange;
      font-weight: bold;
    }
  }
}

.remark-box {
  padding: 10rpx;
  background-color: rgb(235, 235, 235);
  border-radius: 5rpx;
  color: #7f7f7f;
  font-size: 10rpx;
  max-width: 150rpx;
}

.btns-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin: 0 20rpx;

  .bar-item {
    font-size: 8rpx;
    background-color: #efefef;
    padding: 5rpx 10rpx;
    border-radius: 3rpx;
  }
}

.btns-item {
  background-color: #efefef;
  padding: 5rpx 20rpx;
  border-radius: 5rpx;
  margin: 0rpx 15rpx;
  font-size: 12rpx;

  &.confirm {
    color: white;
    background-color: red;
  }

  .btns-item-txt {
    font-size: 10rpx;
    padding: 5rpx 15rpx;
  }

  ::v-deep .u-button {
    padding: 2rpx 20rpx;
  }
}

.radio-list-item {
  display: flex;
  padding: 15rpx;
  background-color: #f5f5f5;
  width: 200rpx;
  justify-content: space-between;
  margin: 5rpx;
  border-radius: 3rpx;

  ::v-deep .u-radio,
  .u-checkbox-label--left {
    margin-right: 10rpx;
  }
}
</style>
